package cn.oldfeel.spark.ui;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.SmackAndroid;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.filetransfer.FileTransfer;
import org.jivesoftware.smackx.filetransfer.FileTransfer.Status;
import org.jivesoftware.smackx.filetransfer.FileTransferListener;
import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jivesoftware.smackx.filetransfer.FileTransferRequest;
import org.jivesoftware.smackx.filetransfer.IncomingFileTransfer;
import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import cn.oldfeel.spark.R;
import cn.oldfeel.spark.base.BaseActivity;
import cn.oldfeel.spark.config.Constant;
import cn.oldfeel.spark.config.UserInfo;
import cn.oldfeel.spark.db.ChatDbHelper;
import cn.oldfeel.spark.fragment.ChatList;
import cn.oldfeel.spark.item.MsgItem;
import cn.oldfeel.spark.util.DateUtil;
import cn.oldfeel.spark.util.DialogUtil;
import cn.oldfeel.spark.util.ETUtil;
import cn.oldfeel.spark.util.XMPPHelper;
import cn.oldfeel.spark.view.ButtonRecord;
import cn.oldfeel.spark.view.ButtonRecord.OnFinishedRecordListener;

/**
 * 聊天界面
 * 
 * @author oldfeel
 * @create Date:2013年11月6日下午4:21:34
 */
@SuppressLint("HandlerLeak")
public class ChatActivity extends BaseActivity implements OnClickListener,
		OnFocusChangeListener {
	public static String RECORD_ROOT_PATH = Environment
			.getExternalStorageDirectory().getAbsolutePath()
			+ "/androidspark/record/";
	String myName;
	String name;
	Button btnVoice;
	ButtonRecord btnRecord;
	EditText etMsg;
	Button btnSend;
	ChatList chatList;
	Chat chat;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.chat_activity);
		SmackAndroid.init(ChatActivity.this);
		myName = UserInfo.getInstance(ChatActivity.this).getName();
		name = getIntent().getStringExtra("name");
		getSupportActionBar().setTitle(name);
		initChat();
		initView();
		initListener();
	}

	private void initChat() {
		chatList = ChatList.newInstance();
		getSupportFragmentManager().beginTransaction()
				.replace(R.id.chat_activity_list, chatList).commit();

		Connection connection = XMPPHelper.getInstance().getConnect();
		ChatManager chatManager = connection.getChatManager();
		chatManager.addChatListener(chatListener);
		FileTransferManager fileTransfreManager = new FileTransferManager(
				connection);
		fileTransfreManager.addFileTransferListener(fileTransferListener);

		chat = chatManager.createChat(name + "@" + Constant.DOMAIN, null);
	}

	private void initView() {
		btnVoice = (Button) findViewById(R.id.chat_activity_voice);
		btnRecord = (ButtonRecord) findViewById(R.id.chat_activity_record);
		etMsg = (EditText) findViewById(R.id.chat_activity_msg);
		btnSend = (Button) findViewById(R.id.chat_activity_send);
	}

	private void initListener() {
		btnVoice.setOnClickListener(this);
		btnSend.setOnClickListener(this);
		etMsg.setOnFocusChangeListener(this);
		btnRecord.setOnFinishedRecordListener(finishedRecordListener);
	}

	/**
	 * 接收信息监听
	 */
	private ChatManagerListener chatListener = new ChatManagerListener() {

		@Override
		public void chatCreated(Chat chat, boolean arg1) {
			chat.addMessageListener(new MessageListener() {
				public void processMessage(Chat arg0, Message msg) {
					chatList.add(msg, name);
					ChatDbHelper.getInstance(ChatActivity.this).insertMsg(msg);
				}
			});
		}
	};
	/**
	 * 录音完成监听
	 */
	private OnFinishedRecordListener finishedRecordListener = new OnFinishedRecordListener() {

		@Override
		public void onFinishedRecord(String audioPath, int time) {
			Log.i("RECORD!!!", "finished!!!!!!!!!! save to " + audioPath);

			if (audioPath != null) {
				try {
					String[] pathStrings = audioPath.split("/"); // 文件名
					String fileName = null;
					if (pathStrings != null && pathStrings.length > 0) {
						fileName = pathStrings[pathStrings.length - 1];
					}

					// 自己显示消息
					MsgItem myChatMsg = new MsgItem(UserInfo.getInstance(
							ChatActivity.this).getName(), time + "”语音消息",
							DateUtil.getDate(), MsgItem.FROM_TYPE[1],
							MsgItem.TYPE[0], MsgItem.STATUS[3], time + "",
							fileName);
					chatList.add(myChatMsg);

					// 发送 对方的消息
					MsgItem sendChatMsg = new MsgItem(UserInfo.getInstance(
							ChatActivity.this).getName(), time + "”语音消息",
							DateUtil.getDate(), MsgItem.FROM_TYPE[0],
							MsgItem.TYPE[0], MsgItem.STATUS[3], time + "",
							fileName);

					// 发送消息
					chat.sendMessage(MsgItem.toJson(sendChatMsg));
					sendFile(audioPath, myChatMsg);//
				} catch (Exception e) {
					e.printStackTrace();
				}
			} else {
				Toast.makeText(ChatActivity.this, "发送失败", Toast.LENGTH_SHORT)
						.show();
			}

		}
	};
	/**
	 * 接收文件监听
	 */
	private FileTransferListener fileTransferListener = new FileTransferListener() {

		public void fileTransferRequest(FileTransferRequest request) {
			// Check to see if the request should be accepted
			Log.d("receivedFile ", " receive file");
			if (shouldAccept(request)) {
				// Accept it
				IncomingFileTransfer transfer = request.accept();
				try {
					System.out.println(request.getFileName());
					File rootFile = new File(RECORD_ROOT_PATH);
					if (!rootFile.exists()) {
						rootFile.mkdirs();
					}
					File file = new File(RECORD_ROOT_PATH
							+ request.getFileName());
					transfer.recieveFile(file);
					MsgItem msgInfo = queryMsgForListMsg(file.getName());
					msgInfo.setFilePath(file.getPath());// 更新 filepath
					new MyFileStatusThread(transfer, msgInfo).start();
				} catch (XMPPException e) {
					e.printStackTrace();
				}
			} else {
				// Reject it
				request.reject();
				String[] args = new String[] { myName, request.getFileName(),
						DateUtil.getDate(), "IN", MsgItem.TYPE[0],
						MsgItem.STATUS[1] };
				MsgItem msgInfo = new MsgItem(args[0], "redio", args[2],
						args[3], MsgItem.TYPE[0], MsgItem.STATUS[1]);
				// 在handler里取出来显示消息
				android.os.Message msg = handler.obtainMessage();
				msg.what = 5;
				msg.obj = msgInfo;
				handler.sendMessage(msg);
			}
		}
	};

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.chat_activity_voice:
			showRecord();
			break;
		case R.id.chat_activity_send:
			send();
			break;
		default:
			break;
		}
	}

	/**
	 * 显示录音按钮
	 */
	private void showRecord() {
		ETUtil.hideSoftKeyboard(ChatActivity.this, etMsg);
		btnRecord.setVisibility(View.VISIBLE);
	}

	/**
	 * 发送
	 */
	private void send() {
		if (ETUtil.isEmpty(etMsg)) {
			DialogUtil.getInstance().showToast(ChatActivity.this, "不能为空");
			return;
		}
		try {
			// 自己显示消息
			MsgItem chatMsg = new MsgItem(myName, ETUtil.getText(etMsg),
					DateUtil.getDate(), MsgItem.FROM_TYPE[1]);
			chatList.add(chatMsg);
			// 发送对方
			MsgItem sendChatMsg = new MsgItem(UserInfo.getInstance(
					ChatActivity.this).getName(), ETUtil.getText(etMsg),
					DateUtil.getDate(), MsgItem.FROM_TYPE[0]);
			chat.sendMessage(MsgItem.toJson(sendChatMsg));
			ChatDbHelper.getInstance(ChatActivity.this).insertMsg(chatMsg);
		} catch (XMPPException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 是否接收
	 * 
	 * @param request
	 * @return
	 */
	private boolean shouldAccept(FileTransferRequest request) {
		return true;
	}

	/**
	 * 发送文件
	 * 
	 * @param path
	 */
	public void sendFile(String path, MsgItem msg) {
		/**
		 * 发送文件
		 */
		// Create the file transfer manager
		FileTransferManager sendFilemanager = new FileTransferManager(
				XMPPHelper.getInstance().getConnect());

		// Create the outgoing file transfer
		OutgoingFileTransfer sendTransfer = sendFilemanager
				.createOutgoingFileTransfer(name + "/" + "smack");
		// Send the file
		try {
			sendTransfer.sendFile(new java.io.File(path), "send file");
			new MyFileStatusThread(sendTransfer, msg).start();
		} catch (XMPPException e) {
			e.printStackTrace();
		}
	}

	class MyFileStatusThread extends Thread {
		private FileTransfer transfer;
		private MsgItem msg;

		public MyFileStatusThread(FileTransfer tf, MsgItem msg) {
			transfer = tf;
			this.msg = msg;
		}

		public void run() {
			System.out.println(transfer.getStatus());
			System.out.println(transfer.getProgress());
			android.os.Message message = new android.os.Message();// handle
			message.what = 3;
			while (!transfer.isDone()) {
				System.out.println(transfer.getStatus());
				System.out.println(transfer.getProgress());
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

			}

			if (transfer.getStatus().equals(Status.error)) {
				msg.setReceive(MsgItem.STATUS[2]);
			} else if (transfer.getStatus().equals(Status.refused)) {
				msg.setReceive(MsgItem.STATUS[1]);
			} else {
				msg.setReceive(MsgItem.STATUS[0]);// 成功

			}

			handler.sendMessage(message);
		}
	}

	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case 1:
				MsgItem chatMsg = MsgItem.analyseMsgBody(msg.obj.toString());
				if (chatMsg != null) {
					chatList.add(chatMsg);// 添加到聊天消息
				}

				break;
			case 2: // 发送文件

				break;
			case 3: // 更新文件发送状态
				chatList.notifyDataSetChanged();
				break;
			case 5: // 接收文件
				MsgItem msg2 = (MsgItem) msg.obj;
				System.out.println(msg2.getFrom());
				chatList.add(msg2);
			default:
				break;
			}
		};
	};

	/**
	 * 从list 中取出 分拣名称相同的 Msg
	 */
	private MsgItem queryMsgForListMsg(String filePath) {
		MsgItem msg = null;
		List<MsgItem> listMsg = new ArrayList<MsgItem>();
		for (int i = listMsg.size() - 1; i >= 0; i--) {
			msg = listMsg.get(i);
			if (filePath != null && filePath.contains(msg.getFileName())) {// 对方传过来的只是文件的名称
				return msg;
			}
		}
		return msg;
	}

	/**
	 * 输入框获取焦点后隐藏录音按钮
	 */
	@Override
	public void onFocusChange(View v, boolean hasFocus) {
		if (hasFocus) {
			btnRecord.setVisibility(View.GONE);
		}
	}
}
